package com.lmmob.autotest.uitest.controls;

import org.apache.commons.lang.StringUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

import java.util.ArrayList;
import java.util.List;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.hasItem;

public class CheckBoxGroup extends Control implements ValueSettable {
    private String name;

    public CheckBoxGroup(String name, WebDriver webDriver) {
        super(webDriver);
        this.name = name;
    }

    @Override
    protected String getSelfQuery() {
        return String.format(".query(\"checkboxgroup[fieldLabel='%s']\")[0]", name);
    }

    @Override
    protected String getName() {
        return this.name;
    }

    public void setValue(String value) {
        clearAll();
        String[] valueArr = StringUtils.split(value, ",");
        String subQuery = ".query(\"[boxLabel='%s']\")[0]";
        for (String subValue : valueArr) {
            String id = (String) runScript("return " + this.getQuery() + String.format(subQuery, subValue) + ".id");
            findElement(By.id(id)).findElement(By.tagName("input")).click();
        }
    }

    private void clearAll() {
        Long len = (Long) runScript("return " + getQuery() + ".items.items.length");
        for (int i = 0; i < len; ++i) {
            Boolean checked = (Boolean) runScript("return " + this.getQuery() + String.format(".items.items[%s].checked", i));
            if (checked) {
                String id = (String) runScript("return " + this.getQuery() + String.format(".items.items[%s].id", i));
                findElement(By.id(id)).findElement(By.tagName("input")).click();
            }
        }
    }

    public void verifyValue(String expected) {
        List<String> actual = getCheckedValues();
        String[] expecteds = StringUtils.split(expected, ",");
        assertThat(String.format("CheckBoxGroup[name='%s']", this.name), actual.size(), is(expecteds.length));
        for (String subExpected : expecteds) {
            assertThat(String.format("CheckBoxGroup[name='%s']", this.name), actual, hasItem(subExpected));
        }
    }

    private List<String> getCheckedValues() {
        Long len = (Long) runScript("return " + this.getQuery() + ".items.items.length");
        List<String> actual = new ArrayList<String>();
        for (int i = 0; i < len; ++i) {
            Boolean checked = (Boolean) runScript("return " + this.getQuery() + String.format(".items.items[%s].checked", i));
            if (checked) {
                String value = (String) runScript("return " + this.getQuery() + String.format(".items.items[%s].boxLabel", i));
                actual.add(value.trim());
            }
        }
        return actual;
    }
}
